android versions

Biggs' Apps

for Android devices

  • android home
  • apps
  • testing
  • rants (main)
  • about biggs
  • crossroads

da Blog

blah blah blah blah blah blah.


Orientation Changes!

Sigh. I remember when I was first learning to program on Android devices. Like everyone, I was stunned to find out that during an orientation change, my entire Activity would be destroyed and then have to redraw itself. WTF? The good programmer deep inside was screaming his bloody head off: what kind of completely inefficient crap was this? After all that time and work to go through all those steps to finally get that Activity looking just right, I now have to destroy it all and start again from the beginning? Aaaaaghh!

But after a while, letting the thoughts go through my head, I kind of figured that there wasn't really a better solution. And I learned to live with it.

But I found bugs popping up during orientation changes, and I did some more testing and saw some strange results from my logcat messages. It looked like onCreate() was being called more than once in some cases of an orientation change.

We all know the Activity Life-cycle, so when there's an orientation change we expect the Activity to go away in this order: onPause(), onStop(), and then onDestroy().

And then, when the Activity is done all over again for the new orientation, we expect to see the usual calls of onCreate(), onStart(), and onResume(). But that's not what was happening. Do it yourself, write some Log.i(...) statements in these and do an orientation change. I'll wait.

Yup, isn't that weird? Those startup messages are called TWICE! But not always!

Apparently there is more than one thing happening: an orientation change AND a keyboard flipping in/out can cause all this ruckus. Thus the multiple restarts and various other confusions.

I have lots to say about this, but for now I'll just say, blecchh!

That alone is bad enough. But when you add the complexity of an ASyncTask to the loading of an Activity, you've turned a simple build-a-screen class into a giant mess.

So that's the end of today's rant. This is a mess of steaming crap--a hack upon hack upon hack that's so hard to maintain that I wish that Google had done a crappy hack instead of this stupid orientation/ASyncTask stuff. A hack would have been SOOO much easier to deal with! Damn!


ASyncTasks

Ok, the last blog was about the horrible implementation of orientation changes in Android. The fix that Google suggests is to use asynchronous tasks, but these bring their own sets of issues.

Whenever an Activity needs to do something that takes a bit of time, developers need to spin that into a separate thread so that the UI thread doesn't get clogged up (resulting in a less-than-snappy interface at best, an "Application Not Responding (ANR) crash at worse).

Since so many useful things can take a while (web access, database access, file access, even complicated user interfaces), the good people at Google thought they'd provide a built-in way to handle this: ASyncTasks. It's not an easy thing to master, but I've been doing them so often that ASyncTasks feel like old classmates.

Aside from their complexity, there are still two problems with ASyncTasks:
Memory Leaks
Non Permanence

Memory Leaks: Let's say you start up your Activity and need to load up some info from the web. Great, throw up a waiting spinner, set your ASyncTask to go to the web and fetch your data.

But...before you're done loading the data, the user interrupts you (orientation change, pops out a keyboard, gets a phone call, etc.). What happens?

Well, your Activity is killed, and a new one is started. This new Activity begins the process all over again, creating a new ASyncTask to grab that needed info from the web.

But what happened to that old ASyncTask? It wasn't really connected to the old Activity, so it wasn't killed when the old Activity died. And when it's done, it'll hit its onPostExecute() and try to access your old Activity! Yeah, the one that's now in the garbage collector. CRASH!

Try it yourself: just rotate quickly several times. It's pretty easy to make that beautiful program crash like you're back in junior high.

I'd love to say that I've figured everything out, but Ryan has an excellent article detailing the issues here.

Non Permanence: That (now static) ASynchronousTask you have now implemented can only be used once! Yup, try calling myASyncTaskInstance.execute() a second time and...whoa, CRASH!

Not quite sure why this happens, but it does. To me, this severely limits the usability of ASyncTasks as I can't reload my data using this same pattern. Really!

So what's a guy to do? Avoid all this junk completely and do it the real Android way: Services. I'll go into this in more detail when I have time, but here's a hint: IntentService coupled with Parcelable/Serializable is a truly useful thing.


"Android Evolution" created by Manu Cornet, http://www.bonkersworld.net. All else is copyright 2013 by Scott M. Biggs and Sleep Furiously Productions. Not that that means much these days.